// i2c_temp_sensor.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>

#define DEVICE_NAME "i2c_temp_sensor"
#define I2C_ADDR 0x48 // LM75 的 I2C 地址
#define TEMP_REG 0x00 // 温度寄存器

static struct i2c_client *temp_client;
static int major_number;

// 打开设备
static int temp_open(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Temperature sensor device opened\n");
    return 0;
}

// 读取温度数据
static ssize_t temp_read(struct file *file, char __user *user_buffer, size_t count, loff_t *offset) {
    int ret;
    char temp_data[2];
    int temperature;

    // 读取温度寄存器
    ret = i2c_smbus_read_i2c_block_data(temp_client, TEMP_REG, 2, temp_data);
    if (ret < 0) {
        return ret; // 发生错误
    }

    // 将读取的温度数据转换为整数
    temperature = (temp_data[0] << 8) | temp_data[1];
    temperature = temperature >> 5; // LM75 的温度数据格式

    // 将温度数据复制到用户空间
    if (copy_to_user(user_buffer, &temperature, sizeof(temperature))) {
        return -EFAULT; // 发生错误
    }

    printk(KERN_INFO "Read temperature: %d\n", temperature);
    return sizeof(temperature); // 返回读取的字节数
}

// 关闭设备
static int temp_close(struct inode *inode, struct file *file) {
    printk(KERN_INFO "Temperature sensor device closed\n");
    return 0;
}

// 文件操作结构体
static struct file_operations fops = {
    .owner = THIS_MODULE,
    .open = temp_open,
    .read = temp_read,
    .release = temp_close,
};

// I2C 设备的匹配结构
static const struct i2c_device_id temp_id[] = {
    { DEVICE_NAME, 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, temp_id);

// I2C 驱动的结构体
static struct i2c_driver temp_driver = {
    .driver = {
        .name = DEVICE_NAME,
        .owner = THIS_MODULE,
    },
    .id_table = temp_id,
};

// 初始化模块
static int __init temp_sensor_init(void) {
    major_number = register_chrdev(0, DEVICE_NAME, &fops);
    if (major_number < 0) {
        printk(KERN_ALERT "Failed to register temperature sensor device\n");
        return major_number;
    }

    // 注册 I2C 驱动
    return i2c_add_driver(&temp_driver);
}

// 卸载模块
static void __exit temp_sensor_exit(void) {
    i2c_del_driver(&temp_driver); // 卸载 I2C 驱动
    unregister_chrdev(major_number, DEVICE_NAME); // 注销字符设备
    printk(KERN_INFO "Temperature sensor device unregistered\n");
}

module_init(temp_sensor_init);
module_exit(temp_sensor_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple I2C temperature sensor driver");

/*

实现一个 I2C 设备驱动，能够与一个外部传感器（如温度传感器）进行通信，并将数据传递给用户空间。

读取温度值
cat /dev/i2c_temp_sensor

*/